import * as THREE from 'three';

export class FlightController {
  constructor() {
    this.position = new THREE.Vector3(0, 2, 0);
    this.rotation = new THREE.Euler(0, 0, 0);
    this.velocity = new THREE.Vector3(0, 0, 0);
    this.angularVelocity = new THREE.Euler(0, 0, 0);

    // Flight parameters - enhanced for better keyboard control
    this.maxSpeed = 8;
    this.maxAltitude = 15;
    this.minAltitude = 0.2;
    this.acceleration = 0.15;
    this.deceleration = 0.92;
    this.rotationSpeed = 0.03;

    // Control states
    this.isFlying = false;
    this.autopilot = false;
    this.currentMission = null;
    this.missionProgress = 0;

    // Telemetry
    this.telemetry = {
      altitude: 2,
      speed: 0,
      battery: 100,
      gpsSignal: 100,
      temperature: 25,
      heading: 0,
      pitch: 0,
      roll: 0
    };

    // Input states
    this.inputs = {
      forward: false,
      backward: false,
      left: false,
      right: false,
      up: false,
      down: false,
      rotateLeft: false,
      rotateRight: false
    };
  }

  // Manual control methods
  setInput(input, active) {
    if (this.inputs.hasOwnProperty(input)) {
      this.inputs[input] = active;
    }
  }

  // Update flight physics
  update(deltaTime) {
    if (!this.isFlying && !this.autopilot) return;

    // Handle manual inputs
    if (!this.autopilot) {
      this.handleManualControls(deltaTime);
    } else {
      this.handleAutopilot(deltaTime);
    }

    // Apply physics
    this.applyPhysics(deltaTime);

    // Update telemetry
    this.updateTelemetry();

    // Apply constraints
    this.applyConstraints();
  }

  handleManualControls(deltaTime) {
    const acceleration = this.acceleration * deltaTime * 60;
    const rotationAccel = this.rotationSpeed * deltaTime * 60;

    // Forward/Backward (relative to drone's rotation)
    if (this.inputs.forward) {
      const forward = new THREE.Vector3(0, 0, -acceleration);
      forward.applyEuler(this.rotation);
      this.velocity.add(forward);
    }
    if (this.inputs.backward) {
      const backward = new THREE.Vector3(0, 0, acceleration);
      backward.applyEuler(this.rotation);
      this.velocity.add(backward);
    }

    // Left/Right (relative to drone's rotation)
    if (this.inputs.left) {
      const left = new THREE.Vector3(-acceleration, 0, 0);
      left.applyEuler(this.rotation);
      this.velocity.add(left);
    }
    if (this.inputs.right) {
      const right = new THREE.Vector3(acceleration, 0, 0);
      right.applyEuler(this.rotation);
      this.velocity.add(right);
    }

    // Up/Down (always world-relative)
    if (this.inputs.up) {
      this.velocity.y += acceleration;
    }
    if (this.inputs.down) {
      this.velocity.y -= acceleration;
    }

    // Rotation
    if (this.inputs.rotateLeft) {
      this.angularVelocity.y += rotationAccel;
    }
    if (this.inputs.rotateRight) {
      this.angularVelocity.y -= rotationAccel;
    }
  }

  handleAutopilot(deltaTime) {
    if (!this.currentMission) return;

    const mission = this.currentMission;
    const currentWaypoint = mission.waypoints[Math.floor(this.missionProgress)];

    if (!currentWaypoint) {
      this.completeMission();
      return;
    }

    // Navigate to waypoint
    const targetPosition = new THREE.Vector3(...currentWaypoint.position);
    const direction = targetPosition.clone().sub(this.position).normalize();
    const distance = this.position.distanceTo(targetPosition);

    if (distance > 0.5) {
      // Move towards waypoint
      const speed = Math.min(this.maxSpeed * 0.5, distance);
      this.velocity.copy(direction.multiplyScalar(speed * deltaTime));

      // Face movement direction
      const targetRotation = Math.atan2(direction.x, direction.z);
      this.angularVelocity.y = (targetRotation - this.rotation.y) * 0.1;
    } else {
      // Reached waypoint
      this.missionProgress += deltaTime * 0.5; // Adjust speed as needed

      // Execute waypoint action
      if (currentWaypoint.action) {
        this.executeWaypointAction(currentWaypoint.action);
      }
    }
  }

  applyPhysics(deltaTime) {
    // Apply velocity to position
    this.position.add(this.velocity.clone().multiplyScalar(deltaTime));

    // Apply angular velocity to rotation
    this.rotation.x += this.angularVelocity.x * deltaTime;
    this.rotation.y += this.angularVelocity.y * deltaTime;
    this.rotation.z += this.angularVelocity.z * deltaTime;

    // Apply deceleration
    this.velocity.multiplyScalar(this.deceleration);
    this.angularVelocity.x *= this.deceleration;
    this.angularVelocity.y *= this.deceleration;
    this.angularVelocity.z *= this.deceleration;

    // Limit speed
    if (this.velocity.length() > this.maxSpeed) {
      this.velocity.normalize().multiplyScalar(this.maxSpeed);
    }
  }

  applyConstraints() {
    // Altitude constraints
    this.position.y = Math.max(this.minAltitude, Math.min(this.maxAltitude, this.position.y));

    // Rotation constraints (prevent extreme tilting)
    this.rotation.x = Math.max(-Math.PI/6, Math.min(Math.PI/6, this.rotation.x));
    this.rotation.z = Math.max(-Math.PI/6, Math.min(Math.PI/6, this.rotation.z));
  }

  updateTelemetry() {
    this.telemetry.altitude = this.position.y;
    this.telemetry.speed = this.velocity.length();
    this.telemetry.heading = (this.rotation.y * 180 / Math.PI + 360) % 360;
    this.telemetry.pitch = this.rotation.x * 180 / Math.PI;
    this.telemetry.roll = this.rotation.z * 180 / Math.PI;

    // Simulate battery drain
    if (this.isFlying) {
      this.telemetry.battery = Math.max(0, this.telemetry.battery - 0.01);
    }
  }

  // Mission control
  startMission(mission) {
    this.currentMission = mission;
    this.missionProgress = 0;
    this.autopilot = true;
    this.isFlying = true;
  }

  completeMission() {
    this.currentMission = null;
    this.missionProgress = 0;
    this.autopilot = false;
  }

  executeWaypointAction(action) {
    switch (action.type) {
      case 'hover':
        this.velocity.set(0, 0, 0);
        break;
      case 'scan':
        // Rotate to scan area
        this.angularVelocity.y = 0.5;
        break;
      case 'land':
        this.land();
        break;
      default:
        break;
    }
  }

  // Flight modes
  takeOff() {
    this.isFlying = true;
    this.position.y = Math.max(this.position.y, 2);
  }

  land() {
    this.isFlying = false;
    this.autopilot = false;
    this.velocity.set(0, -1, 0);
  }

  emergencyStop() {
    this.velocity.set(0, 0, 0);
    this.angularVelocity.set(0, 0, 0);
    this.autopilot = false;
  }

  // Get current state for rendering
  getState() {
    return {
      position: this.position.clone(),
      rotation: this.rotation.clone(),
      velocity: this.velocity.clone(),
      isFlying: this.isFlying,
      autopilot: this.autopilot,
      telemetry: { ...this.telemetry },
      missionProgress: this.missionProgress,
      currentMission: this.currentMission
    };
  }
}
